home *** CD-ROM | disk | FTP | other *** search
- /*
- * sample program for demonstrating the debugging calls
- * Written by Alex Kiernan
- */
-
- #include <mintbind.h>
- #include <stddef.h>
-
- typedef struct _context {
- long regs[15]; /* registers d0-d7, a0-a6 */
- long usp; /* user stack pointer (a7) */
- short sr; /* status register */
- long pc; /* program counter */
- long ssp; /* supervisor stack pointer */
- long term_vec; /* GEMDOS terminate vector (0x102) */
- /*
- * AGK: if running on a TT and the user is playing with the FPU then we
- * must save and restore the context. We should also consider this for
- * I/O based co-processors, although this may be difficult due to
- * possibility of a context switch in the middle of an I/O handshaking
- * exchange.
- */
- unsigned char fstate[216]; /* FPU internal state */
- long fregs[3*8]; /* registers fp0-fp7 */
- long fctrl[3]; /* FPCR/FPSR/FPIAR */
- /*
- * AGK: for long (time-wise) co-processor instructions (FMUL etc.), the
- * FPU returns NULL, come-again with interrupts allowed primitives. It
- * is highly likely that a context switch will occur in one of these if
- * running a mathematically intensive application, hence we must handle
- * the mid-instruction interrupt stack. We do this by saving the extra
- * 3 long words and the stack format word here.
- */
- unsigned short sfmt; /* stack frame format identifier */
- short internal[42]; /* internal state -- see framesizes[] for size */
- char ptrace; /* trace exception is pending */
- } CONTEXT;
-
- #define PPROCADDR (('P'<< 8) | 1)
- #define PBASEADDR (('P'<< 8) | 2)
- #define PCTXTSIZE (('P'<< 8) | 3)
- #define PSETFLAGS (('P'<< 8) | 4)
- #define PGETFLAGS (('P'<< 8) | 5)
- #define PTRACESFLAGS (('P'<< 8) | 6)
- #define PTRACEGFLAGS (('P'<< 8) | 7)
- # define P_ENABLE (1 << 0) /* enable tracing */
- #ifdef NOTYETDEFINED
- # define P_DOS (1 << 1) /* trace DOS calls - unimplemented */
- # define P_BIOS (1 << 2) /* trace BIOS calls - unimplemented */
- # define P_XBIOS (1 << 3) /* trace XBIOS calls - unimplemented */
- #endif
-
- #define PTRACEGO (('P'<< 8) | 8) /* these 4 must be together */
- #define PTRACEFLOW (('P'<< 8) | 9)
- #define PTRACESTEP (('P'<< 8) | 10)
- #define PTRACE11 (('P'<< 8) | 11)
-
- /* lseek() origins */
- #define SEEK_SET 0 /* from beginning of file */
- #define SEEK_CUR 1 /* from current location */
- #define SEEK_END 2 /* from end of file */
-
- #define WNOHANG 1
- #define WUNTRACED 2
-
- /* these definitions are incompatible with <sys/wait.h> */
- #define WIFEXITED(x) ((int)((x) & 0xFF00) == 0)
- #define WEXITSTATUS(x) ((int)((x) & 0xFF))
-
- #define WIFSIGNALED(x) (((int)((x) & 0xFF00) > 0) && ((int)(((x) & 0xFF) == 0)))
- #define WTERMSIG(x) ((int)(((x) & 0xFF00) >> 8))
-
- #define WIFSTOPPED(x) (((int)((x) & 0xFF) == 0x7F) && ((int)(((x) >> 8) & 0xFF) != 0))
- #define WSTOPSIG(x) ((int)(((x) >> 8) & 0xFF))
-
- #define SIGTRAP 5 /* trace trap */
-
- void
- dumpCTXT(ctxt)
- CONTEXT *ctxt;
- {
- int i, j;
-
- for (i = 0; i < 16; i += 4) {
- for (j = 0; j < 4; j++) {
- /* oh dear... we output too many commas - c'est la vie */
- printf("%c%d=$%08lx, ", i < 8 ? 'D' : 'A',
- i + j - (i >= 8 ? 8 : 0),
- ctxt[0].regs[i + j]);
- }
- putchar('\n');
- }
- printf("SR=$%04x\n", ctxt[0].sr);
- printf("PC=$%08lx\n", ctxt[0].pc);
- printf("SSP=$%08lx\n", ctxt[0].ssp);
- printf("term_vec=$%08lx\n", ctxt[0].term_vec);
- printf("fstate[0]=%u\n", ctxt[0].fstate[0]);
- for (i = 0; i < 8; i++) {
- printf("FP%d=$%08lx%08lx%08lx\n",
- i,
- ctxt[0].fregs[i * 3 + 0],
- ctxt[0].fregs[i * 3 + 1],
- ctxt[0].fregs[i * 3 + 2]);
- }
- printf("frame format=%u\n", ctxt[0].sfmt >> 12);
- printf("vector offset=$%x\n", ctxt[0].sfmt & 0xfff);
- /* could print internal state here internal[0..41] */
- }
-
- int
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int pid;
- unsigned long status;
- int fd;
- char fpid[13];
- CONTEXT ctxt;
- long pctxt;
- long sizeof_ctxt;
- unsigned short sig;
-
- if (isdigit(*argv[1])) {
- pid = atoi(argv[1]);
- sprintf(fpid, "U:\\PROC\\.%03d", pid);
- fd = Fopen(fpid, 0);
- sig = 1;
- Fcntl(fd, (long)&sig, PTRACESFLAGS); /* capture it */
- Pkill(pid, SIGTRAP); /* and stop it */
- }
- else {
- pid = Pexec(0x8000 | 100, argv[1], "\0", NULL);
- /* check pid */
- printf("pid = %d\n", pid);
- sprintf(fpid, "U:\\PROC\\.%03d", pid);
- fd = Fopen(fpid, 0);
- }
- /* check fd */
- Fcntl(fd, (long)&pctxt, PPROCADDR);
- Fcntl(fd, (long)&sizeof_ctxt, PCTXTSIZE);
- pctxt -= 2 * sizeof_ctxt;
-
- do {
- status = Pwait3(WUNTRACED, NULL);
- if (WIFSTOPPED(status)) {
- printf("pid = %d\, WSTOPSIG = %d\n", (int)(status >> 16), WSTOPSIG(status));
- Fseek((long)pctxt, fd, SEEK_SET);
- Fread(fd, sizeof(ctxt), &ctxt); /* note _not_ sizeof_ctxt */
- dumpCTXT(&ctxt);
- switch (Cconin() & 0xff) {
- case 's':
- case 'S':
- Fcntl(fd, (long)NULL, PTRACESTEP); /* single step */
- break;
-
- case 'g':
- case 'G':
- Fcntl(fd, (long)NULL, PTRACEGO); /* go */
- break;
-
- case 'f':
- case 'F':
- Fcntl(fd, (long)NULL, PTRACEFLOW); /* go to flow change */
- break;
-
- case 'x':
- case 'X':
- sig = WSTOPSIG(status);
- Fcntl(fd, (long)&sig, PTRACEGO); /* kill it */
- break;
- }
- }
- putchar('\n');
- } while (!WIFEXITED(status) && !WIFSIGNALED(status));
- if (WIFEXITED(status))
- printf("pid = %d, WEXITSTATUS = %d\n", (int)(status >> 16), WEXITSTATUS(status));
- else
- printf("pid = %d, WTERMSIG = %d\n", (int)(status >> 16), WTERMSIG(status));
- Fclose(fd); /* but the process is dead... (Jim!) */
- return 0;
- }
-